package order.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.feign.constant.AuthServerConstant;
import com.feign.constant.CartConstant;
import com.feign.domain.SpuInfo;
import com.feign.product.SpuInfoFeignService;
import com.feign.utils.R;
import com.feign.vo.CartInfo;
import com.feign.vo.LoginResVo;
import order.domain.Order;
import order.domain.OrderItem;
import order.service.OrderItemService;
import order.service.OrderService;
import order.mapper.OrderMapper;
import order.vo.submitOrder.OrderDetail;
import order.vo.submitOrder.SubmitOrderVo;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author panghu
 * @description 针对表【oms_order(订单)】的数据库操作Service实现
 * @createDate 2023-03-04 21:01:40
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order>
        implements OrderService {

    @Autowired
    private OrderItemService orderItemService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private SpuInfoFeignService spuInfoFeignService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public Page<Map<String, Object>> getOrderListWithPage(Integer page, Integer limit, HttpServletRequest request) {
        Page<Map<String, Object>> orderPage = new Page<>(page, limit);
        // todo 查询当前登录人的订单列表
        // 获取请求头中的token
        String token = request.getHeader("token");
        //String userTempId = request.getHeader("userTempId");
        // 验证身份
        String user = redisTemplate.opsForValue().get(AuthServerConstant.TOKEN + token);
        if (ObjectUtils.isEmpty(user)) {
            return null;
        }
        //redisTemplate.opsForValue().get(AuthServerConstant.LOGIN_USER)
        LoginResVo loginResVo = JSONUtil.toBean(user, LoginResVo.class);
        Page<Map<String, Object>> mapPage = this.baseMapper.selectMapsPage(orderPage, new LambdaQueryWrapper<Order>().eq(Order::getMemberId, loginResVo.getUserId()));
        mapPage.getRecords().forEach(item -> {
            Long orderId = (Long) item.get("id");
            // 根据orderId查找订单项
            List<OrderItem> orderItems = orderItemService.list(new LambdaQueryWrapper<OrderItem>().eq(OrderItem::getOrderId, orderId));
            BigDecimal totalAmount = BigDecimal.ZERO;
            List<OrderDetail> orderDetailList = new ArrayList<>();
            for (OrderItem orderItem : orderItems) {
                OrderDetail orderDetail = new OrderDetail();
                orderDetail.setImgUrl(orderItem.getSkuPic());
                orderDetail.setId(orderItem.getId());
                orderDetail.setOrderPrice(orderItem.getRealAmount());
                orderDetail.setOrderId(orderItem.getOrderId());
                orderDetail.setSkuId(orderItem.getSkuId());
                orderDetail.setSkuName(orderItem.getSkuName());
                orderDetail.setSkuNum(orderItem.getSkuQuantity());
                orderDetail.setSourceId(orderItem.getSkuId());
                orderDetail.setSplitTotalAmount(orderItem.getSkuPrice().multiply(BigDecimal.valueOf(orderItem.getSkuQuantity())));
                totalAmount = totalAmount.add(orderDetail.getSplitTotalAmount());
                orderDetailList.add(orderDetail);
            }
            item.put("orderDetailList", orderDetailList);
            item.put("totalAmount", totalAmount);
        });
        return mapPage;
    }

    @Override
    @Transactional
    public R submitOrder(SubmitOrderVo submitOrderVo, String tradeNo, HttpServletRequest request) {
        // 判断是否重复提交订单
        boolean exists = this.baseMapper.exists(new LambdaQueryWrapper<Order>().eq(Order::getOrderSn, tradeNo));
        if (!exists) {
            // 查询用户
            // 获取请求头中的token
            String token = request.getHeader("token");
            if (ObjectUtils.isEmpty(token)) {
                return R.error("请登录后再提交订单");
            }
            String user = redisTemplate.opsForValue().get(AuthServerConstant.TOKEN + token);
            LoginResVo loginResVo = JSONUtil.toBean(user, LoginResVo.class);
            // 创建订单数据，返回订单编号和id
            Order order = new Order();
            order.setOrderSn(tradeNo);
            order.setCreateTime(new Date());
            order.setMemberId(loginResVo.getUserId());
            order.setReceiverPhone(submitOrderVo.getConsigneeTel());
            order.setReceiverName(submitOrderVo.getConsignee());
            order.setReceiverDetailAddress(submitOrderVo.getDeliveryAddress());
            order.setNote(submitOrderVo.getOrderComment());
            order.setMemberUsername(loginResVo.getName());
            order.setTotalAmount(submitOrderVo.getOrderTotalPrice());
            this.baseMapper.insert(order);
            //  创建订单项数据。
            List<OrderDetail> orderDetailList = submitOrderVo.getOrderDetailList();
            if (!ObjectUtils.isEmpty(orderDetailList)) {
                List<OrderItem> orderItemList = orderDetailList.stream().map(item -> {
                    OrderItem orderItem = new OrderItem();
                    orderItem.setOrderSn(tradeNo);
                    orderItem.setSkuName(item.getSkuName());
                    orderItem.setSkuPic(item.getImgUrl());
                    orderItem.setSkuPrice(item.getOrderPrice());
                    orderItem.setSkuId(item.getSkuId());
                    orderItem.setSkuQuantity(item.getSkuNum());
                    // orderId，使得订单和订单项关联起来。
                    orderItem.setOrderId(order.getId());
                    // 调用远程服务，根据skuId查询skuInfo
                    SpuInfo spuInfo = spuInfoFeignService.findSpuInfoBySkuId(item.getSkuId());
                    orderItem.setSpuId(spuInfo.getId());
                    //orderItem.setSpuBrand();
                    orderItem.setSpuName(spuInfo.getSpuName());
                    orderItem.setCategoryId(spuInfo.getCatalogId());
                    //orderItem.setSpuPic();
                    return orderItem;
                }).collect(Collectors.toList());
                // 批量插入
                orderItemService.saveBatch(orderItemList);
            }
            // 删除购物车里的商品，消息队列
            // 发送消息-购物车的key
            if (!ObjectUtils.isEmpty(token)) {
                // 身份验证通过
                String cartKey = CartConstant.CART_PREFIX + loginResVo.getUserId().toString();
                if (!ObjectUtils.isEmpty(cartKey)) {
                    // 删除临时购物车的key
                    rabbitTemplate.convertAndSend("cartKey", cartKey);
                    //redisTemplate.delete(cartKey);
                }
            }
            return R.ok().setData(tradeNo);
        }
        return R.error("不要重复创建订单");
    }

    @Override
    @Transactional
    public void delOrderById(Long orderId) {
        // 删除订单
        this.baseMapper.deleteById(orderId);
        // 删除属于该订单的订单项
        List<OrderItem> orderItems = orderItemService.list(new LambdaQueryWrapper<OrderItem>().eq(OrderItem::getOrderId, orderId));
        List<Long> orderItemIds = orderItems.stream().map(OrderItem::getId).collect(Collectors.toList());
        orderItemService.removeBatchByIds(orderItemIds);
    }
}




